//
//  UIViewController+Ext.swift
//  TTCOM-iOS
//
//  Created by Toj on 2/23/22.
//

import UIKit

public extension UIViewController {
    
    class var vc_topViewController: UIViewController? {
        guard let vc = vc_currentNavigation else {
            let vc = UIApplication.shared.delegate?.window??.rootViewController
            return vc_topViewController(of: vc)
        }
        return vc_topViewController(of: vc.viewControllers.last)
    }
    
    private class func vc_topViewController(of vc: UIViewController?) -> UIViewController? {
        // presented view controller
        if let pvc = vc?.presentedViewController {
            return vc_topViewController(of: pvc)
        }
        
        // UITabBarController
        if let tbc = vc as? UITabBarController,
           let selectedVC = tbc.selectedViewController {
            return vc_topViewController(of: selectedVC)
        }
        
        // UINavigationController
        if let nvc = vc as? UINavigationController,
           let visibleVC = nvc.visibleViewController {
            return vc_topViewController(of: visibleVC)
        }
        
        return vc
    }
    
    var vc_isTopViewController: Bool {
        guard !vc_isCurrentNavigationTopViewController else { return true }
        
        if let _ = presentedViewController {
            return false
        }
        
        return true
    }
    
    var vc_isCurrentNavigationTopViewController: Bool {
        guard let vc = navigationController?.viewControllers.last
        else { return false }
        return self == vc
    }
    
    class var vc_currentNavigationTopViewController: UIViewController? {
        let nav = vc_currentNavigation
        return nav?.viewControllers.last
    }
    
    class var vc_currentNavigation: UINavigationController? {
        guard let tbc = UIApplication.shared.delegate?.window??.rootViewController as? UITabBarController
        else {
            guard let nav = UIApplication.shared.delegate?.window??.rootViewController as? UINavigationController else { return nil }
            return nav
        }
        
        guard let nav = tbc.selectedViewController as? UINavigationController
        else { return nil }
        return nav
    }
}

struct RTAKeys {
    static var reflectionParameterKey = ""
}

public extension UIViewController {
    
    // 弹出方式
    // 1. Add : vc.addChild
    // 2. Moda: vc.present
    // 3. Push: nav.push
    // vc.present必有一个 presentingViewController
    // vc.addChild不会有 presentingViewController
    // nav.push 不会有 presentingViewController
    var st_isPresent: Bool {
        return presentingViewController != nil
    }
   
    private(set) var vc_reflectionParameter: [String: String]? {
        get {
            let associatedValue = objc_getAssociatedObject(self, &RTAKeys.reflectionParameterKey)
            return associatedValue as? [String: String]
        }
        set {
            objc_setAssociatedObject(self, &RTAKeys.reflectionParameterKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    func vc_reflection(parameter: [String:String]? = nil) {
        vc_reflectionParameter = parameter
    }
    
    static func vc_reflection(className: String) -> UIViewController? {
        guard !className.isEmpty else { return nil }
        let separator = "."
        var classComponents = className.components(separatedBy: separator)
        guard !classComponents.isEmpty else { return nil }
        
        guard let productName = Bundle.main.infoDictionary?["CFBundleExecutable"] as? String else { return nil}
        
        if classComponents.count == 1 {
            let cls = classComponents[0]
            classComponents = [productName, cls]
        }
        
        if classComponents.count > 1, classComponents[0] != productName {
            classComponents[0] = productName
        }
        let name = classComponents.joined(separator: separator)
        
        guard let cls = NSClassFromString(name) else { return nil }
        guard let classType = cls as? UIViewController.Type else { return nil }
        // 初始化类相当于oc 从 metaclass -> class
        let vc = classType.init()
        return vc
    }
    
    func vc_addChildAndView(childController: UIViewController) {
        addChild(childController)
        view.addSubview(childController.view)
    }
    
    func vc_removeFromParentAndView() {
        view.removeFromSuperview()
        removeFromParent()
    }
}
